package com.cls.business.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cls.business.entity.*;
import com.cls.business.mapper.DeclareEntrustMapper;
import com.cls.business.mapper.DeclareTopicMapper;
import com.cls.business.mapper.TopicMapper;
import com.cls.business.mapper.TopicPlanMapper;
import com.cls.business.service.*;
import com.cls.business.vo.*;
import com.cls.business.vo.preitem.report.DeclareTopic4PreItemExport;
import com.cls.business.vo.preitem.report.PreItemExport;
import com.cls.common.entity.QueryRequest;
import com.cls.common.enums.DictEnum;
import com.cls.common.exception.MyException;
import com.cls.common.utils.DESUtil;
import com.cls.common.utils.FileUtil;
import com.cls.common.utils.ReportUtil;
import com.cls.system.entity.Configure;
import com.cls.system.entity.SysDict;
import com.cls.system.entity.User;
import com.cls.system.service.IConfigureService;
import com.cls.system.service.ISysDictService;
import com.cls.system.service.ISysFileService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 申报课题表 Service实现
 *
 * @author weimaomao
 * @date 2020-11-10 11:09:57
 */
@Service
@RequiredArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class DeclareTopicServiceImpl extends ServiceImpl<DeclareTopicMapper, DeclareTopic> implements IDeclareTopicService {

    private final ISysFileService sysFileService;
    private final IApplicantInfoService applicantInfoService;

    private final INoticeService noticeService;

    private final IMemberInfoService memberInfoService;
    private final IMemberInfoRecordService memberInfoRecordService;
    private final IAllotmentCapitalService allotmentCapitalService;

    private final IDelayApplyService delayApplyService;

    private final ILeaderProjectService leaderProjectService;
    private final IDraftAchievementService draftAchievementService;

    private final ILogDeclareTopicService logDeclareTopicService;

    private final QualificationReviewService qualificationReviewService;

    private final TopicPlanMapper topicPlanMapper;

    private final TopicMapper topicMapper;
    private final DeclareEntrustMapper declareEntrustMapper;

    private final IMaxIndexService maxIndexService;

    private final ISysDictService sysDictService;

    private final IDeclareEntrustService declareEntrustService;
    @Autowired
    private IEntrustCheckLogService entrustCheckLogService;

    private final IDeclarePlanService declarePlanService;

    private final IConfigureService configureService;

    @Override
    public PageInfo<DeclareTopicVO> findDeclareTopics(QueryRequest request, DeclareTopic declareTopic) {
        LambdaQueryWrapper<DeclareTopic> queryWrapper = new LambdaQueryWrapper<>();
        // 申报课题名称
        if (StringUtils.isNotEmpty(declareTopic.getName())) {
            queryWrapper.like(DeclareTopic::getName, declareTopic.getName());
        }

        // 申报主持人
        if (StringUtils.isNotEmpty(declareTopic.getLeaderName())) {
            queryWrapper.like(DeclareTopic::getLeaderName, declareTopic.getLeaderName());
        }

        // 课题指南编号
        if (StringUtils.isNotEmpty(declareTopic.getTopicCode())) {
            queryWrapper.like(DeclareTopic::getTopicCode, declareTopic.getTopicCode());
        }

        // 年份
        if (StringUtils.isNotEmpty(declareTopic.getYearSearch())) {
            queryWrapper.like(DeclareTopic::getTopicCode, declareTopic.getYearSearch());
        }


        // 学科分类
        if (StringUtils.isNotEmpty(declareTopic.getSubjectTypeCode())) {
            queryWrapper.eq(DeclareTopic::getSubjectTypeCode, declareTopic.getSubjectTypeCode());
        }

        // 申报课题状态
        if (StringUtils.isNotEmpty(declareTopic.getStatusTypeCode())) {
            queryWrapper.eq(DeclareTopic::getStatusTypeCode, declareTopic.getStatusTypeCode());
        }

        // 课题类型
        if (StringUtils.isNotEmpty(declareTopic.getTopicClassifyCode())) {
//            queryWrapper.eq(DeclareTopic::getTopicClassifyCode, declareTopic.getTopicClassifyCode());
            queryWrapper.and(wrapper -> {
                wrapper.eq(DeclareTopic::getTopicClassifyCode, declareTopic.getTopicClassifyCode()).or()
                        .eq(DeclareTopic::getTopicClassifyCode, DictEnum.UNLIMITED.getCode());
            });
        }

        // 申报课题状态
        if (declareTopic.getCreateBy() != null) {
            queryWrapper.eq(DeclareTopic::getCreateBy, declareTopic.getCreateBy());
        }
        queryWrapper.orderByDesc(DeclareTopic::getCreateTime);
        PageHelper.startPage(request.getPageNum(), request.getPageSize());

        List<DeclareTopic> declareTopics = this.list(queryWrapper);
        List<DeclareTopicVO> declareTopicVOs = new ArrayList();
        for (DeclareTopic one : declareTopics) {
            TopicPlan plan = topicPlanMapper.selectByTopicId(one.getTopicId());
            if (plan != null) {
                one.setPlanId(plan.getPlanId());
                one.setStatusCode(plan.getStatusCode());
                one.setYear(plan.getYear());
                Long preItemNoticeId = plan.getPreItemNoticeId();
                one.setIsPreItemNotice(false);
                if (preItemNoticeId != null) {
                    Notice notice = Optional.of(noticeService.getById(preItemNoticeId)).orElse(new Notice());
                    one.setIsPreItemNotice(notice.getIsPublish());
                }
                Configure configure = configureService.getById(plan.getConfigureId());
                if (configure != null) {
                    one.setBusinessType(configure.getBusinessTypeCode());
                }
            }
            DeclareTopicVO declareTopicVO = new DeclareTopicVO(one);
            ApplicantInfo leader = applicantInfoService.getById(one.getApplicantId());
            if (leader != null) {
                declareTopicVO.setLeader(leader);
            }
            declareTopicVOs.add(declareTopicVO);
        }
        PageInfo pageInfo = new PageInfo(declareTopics);
        pageInfo.setList(declareTopicVOs);
        return pageInfo;
    }

    @Override
    public List<DeclareTopic> findDeclareTopics(DeclareTopic declareTopic) {
        LambdaQueryWrapper<DeclareTopic> queryWrapper = new LambdaQueryWrapper<>();
        // TODO 设置查询条件
        if (declareTopic.getTopicId() != null) {
            queryWrapper.eq(DeclareTopic::getTopicId, declareTopic.getTopicId());
        }
        if (StringUtils.isNotEmpty(declareTopic.getStatusTypeCode())) {
            queryWrapper.eq(DeclareTopic::getStatusTypeCode, declareTopic.getStatusTypeCode());
        }
        // 申报课题名称
        if (StringUtils.isNotEmpty(declareTopic.getName())) {
            queryWrapper.like(DeclareTopic::getName, declareTopic.getName());
        }

        // 申报主持人
        if (StringUtils.isNotEmpty(declareTopic.getLeaderName())) {
            queryWrapper.like(DeclareTopic::getLeaderName, declareTopic.getLeaderName());
        }

        // 课题指南编号
        if (StringUtils.isNotEmpty(declareTopic.getTopicCode())) {
            queryWrapper.like(DeclareTopic::getTopicCode, declareTopic.getTopicCode());
        }

        // 年份
        if (StringUtils.isNotEmpty(declareTopic.getYearSearch())) {
            queryWrapper.like(DeclareTopic::getTopicCode, declareTopic.getYearSearch());
        }


        // 学科分类
        if (StringUtils.isNotEmpty(declareTopic.getSubjectTypeCode())) {
            queryWrapper.eq(DeclareTopic::getSubjectTypeCode, declareTopic.getSubjectTypeCode());
        }

        // 申报课题状态
        if (StringUtils.isNotEmpty(declareTopic.getStatusTypeCode())) {
            queryWrapper.eq(DeclareTopic::getStatusTypeCode, declareTopic.getStatusTypeCode());
        }
        queryWrapper.orderByDesc(DeclareTopic::getCreateTime);
        // 申报计划ID
//        if(declareTopic.getPlanId() != null){
//            queryWrapper.eq(DeclareTopic::getPlanId,declareTopic.getPlanId());
//        }
        return this.baseMapper.selectList(queryWrapper);
    }

    @Override
    public List<DeclareTopic> findByTopicIds(List<Long> topicIds) {
        LambdaQueryWrapper<DeclareTopic> queryWrapper = new LambdaQueryWrapper<>();
        if (topicIds != null) {
            queryWrapper.in(DeclareTopic::getTopicId, topicIds);
        }
        // TODO 设置查询条件
        return this.baseMapper.selectList(queryWrapper);
    }

    /**
     * 判断当前申请课题是否过期
     *
     * @param topicId
     */
    private void checkDeclareTopicApply(Long topicId) {
        TopicPlan topicPlan = topicMapper.selectPlanByTopicId(topicId);
        Date applySubmitEndTime = topicPlan.getApplySubmitEndTime();
        Date date = new Date();
        int compareOver = DateUtil.compare(applySubmitEndTime, date);
        int compareNoBegin = DateUtil.compare(topicPlan.getSubmitBeginTime(), date);
        if (compareNoBegin > 0) {
            throw new MyException("对不起，当前课题申请提交还未开始！");
        }

        if (compareOver < 0) {
            throw new MyException("对不起，当前课题申请提交已过期！");
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createDeclareTopic(DeclareTopicVO declareTopicVo) {
        checkDeclareTopicApply(declareTopicVo.getTopicId());
        // 获取主持人信息后进行保存与更新
        ApplicantInfo leader = declareTopicVo.getLeader();
        if (leader != null) {
            String identity = leader.getIdentity();
            if (!StringUtils.isEmpty(identity) && identity.length() == 18) {
                String birth = identity.substring(6, 14);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
                try {
                    leader.setBirthday(sdf.parse(birth));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
            applicantInfoService.saveOrUpdate(leader);
        }

        // 通过课题指南编号去获取课题指南ID
        DeclareTopic declareTopic = declareTopicVo.convertToDeclareTopic();
        declareTopic.setApplicantId(leader.getApplicantId());
        declareTopic.setLeaderName(leader.getName());
        Topic topic = topicMapper.selectById(declareTopic.getTopicId());
        if (topic != null) {
            if (declareTopic.getDeclareId() == null) {
                MaxIndex maxIndex = new MaxIndex();
                maxIndex.setTopicId(declareTopic.getTopicId());
                maxIndex.setType(DictEnum.ANNUAL.getCode());
                String no = getMaxIndex(maxIndex);
                declareTopic.setCode(topic.getTopicCode() + no);
                // 创建时，未申报状态
                declareTopic.setStatusTypeCode(DictEnum.NO_APPLY.getCode());
            }
            declareTopic.setTopicCode(topic.getTopicCode());
        }
        declareTopic.setTopicClassifyCode(DictEnum.ANNUAL.getCode());
        declareTopic.setIsFinish(false);
        saveOrUpdate(declareTopic);

        // 获取成员信息进行保存
        List<MemberInfo> members = declareTopicVo.getMemberInfos();
        if (members != null) {
            for (MemberInfo member : members) {
                member.setDeclareId(declareTopic.getDeclareId());
            }
            members.forEach(item->{
                memberInfoService.saveOrUpdate(item);
            });
        }

        // 获取成员研究成果信息保存与更新
        List<LeaderProject> projects = declareTopicVo.getLeaderProjects();
        if (projects != null) {
            for (LeaderProject project : projects) {
                project.setDeclareId(declareTopic.getDeclareId());
            }
            projects.forEach(item->{
                leaderProjectService.saveOrUpdate(item);
            });
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCheckDeclareTopic(DeclareTopic declareTopic) {
        updateDeclareTopicStatusTypeCode(declareTopic, DictEnum.OPERATOR_CHECK.getCode());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDeclareTopic(DeclareTopicVO declareTopicVo) {
        List<Long> deleteMemberIds = declareTopicVo.getDeleteMemberIds();
        if (deleteMemberIds != null && deleteMemberIds.size() > 0) {
            memberInfoService.removeByIds(deleteMemberIds);
        }
        List<Long> deleteProjectIds = declareTopicVo.getDeleteProjectIds();
        if (deleteProjectIds != null && deleteProjectIds.size() > 0) {
            leaderProjectService.removeByIds(deleteProjectIds);
        }
        createDeclareTopic(declareTopicVo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDeclareTopic(DeclareTopic declareTopic) {
        LambdaQueryWrapper<DeclareTopic> wrapper = new LambdaQueryWrapper<>();
        // TODO 设置删除条件
        // 根据DeclareId删除
        wrapper.eq(DeclareTopic::getDeclareId, declareTopic.getDeclareId());
        this.remove(wrapper);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDeclareTopicStatusTypeCode(DeclareTopic declareTopic, String operatorType) {
        LogDeclareTopic logDeclareTopic = new LogDeclareTopic();
        logDeclareTopic.setStatusTypeCode(declareTopic.getStatusTypeCode());
        logDeclareTopic.setOperatorTime(new Date());
        logDeclareTopic.setOperatorTypeCode(operatorType);
        logDeclareTopic.setReason(declareTopic.getCheckResult());
        logDeclareTopic.setDeclareId(declareTopic.getDeclareId());
        User curUser = (User) SecurityUtils.getSubject().getPrincipal();
        if (curUser != null) {
            logDeclareTopic.setOperatorBy(curUser.getUserId());
        }
        logDeclareTopicService.createLogDeclareTopic(logDeclareTopic);
        saveOrUpdate(declareTopic);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void applyDeclareTopicStatusTypeCode(DeclareTopic declareTopic, Long planId) {
        // 资格审查
        StringBuilder builder = qualificationReviewService.checkQualification(declareTopic, planId);
        declareTopic.setAutoCheckResult(builder.toString());
        updateDeclareTopicStatusTypeCode(declareTopic, DictEnum.OPERATOR_APPLY.getCode());
        saveOrUpdate(declareTopic);
        DeclarePlan declarePlan = declarePlanService.findByDeclareTopicIdAndPlanId(declareTopic.getDeclareId(), planId);
        if (declarePlan == null) {
            declarePlan = new DeclarePlan();
            declarePlan.setPlanId(planId);
            declarePlan.setPlanTopicId(declareTopic.getTopicId());
            declarePlan.setDeclareId(declareTopic.getDeclareId());
            declarePlan.setApplyCount(1);
            declarePlan.setAchievementFormTypeCode(declareTopic.getAchievementFormTypeCode());
            declarePlanService.save(declarePlan);
        }
    }


    /**
     * 魏起成  定评评审查询
     *
     * @param request      QueryRequest
     * @param declareTopic declareTopic
     * @return
     */
    @Override
    public PageInfo<DeclareTopicVO> findDeclareTopicsForEvaluation(QueryRequest request, DeclareTopic declareTopic) {
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<DeclareTopicVO> declareTopicVOs = this.baseMapper.findDeclareTopicsAndTopicPlan(declareTopic);
        PageInfo pageInfo = new PageInfo(declareTopicVOs);
        return pageInfo;
    }


    @Override
    public List<TopicSubjectDetail> countDeclareTopicsBySubjectType(Long topicId, String statusTypeCode) {
        return baseMapper.countDeclareTopicsBySubjectType(topicId, statusTypeCode);
    }

    /**
     * 魏起成
     * 根据状态查询课题并根据年份分组
     *
     * @param statusTypeCode
     * @return
     */
    @Override
    public List<Topic> selectByStatusGroupByYear(String statusTypeCode, String topicClassify) {
        return this.baseMapper.selectByStatusGroupByYear(statusTypeCode, topicClassify);
    }

    /**
     * 魏起成
     * 根据年份查询此年份所有的拟立项审查通过的数据，进行生成编码并修改其状态为立项通过
     *
     * @param year
     */
    @Override
    public void createAnnualCode(Integer year) {
        //查询此年份所有的拟立项审查通过的数据
        String itemCheckPassed = DictEnum.ITEM_CHECK_PASSED.getCode();
        String itemPassed = DictEnum.ITEM_PASSED.getCode();
        List<DeclareTopic> declareTopicList = this.baseMapper.selectByStatusAndYear(itemCheckPassed, year, DictEnum.ANNUAL.getCode());
            /*管理员-结项管理：结项编号的规则为：CLS（年份）课题类别编号，如CLS（2020）A001
         课题类别：A重大课题、B重点课题、C一般课题、Y青年调研项目、D自选课题、J基础研究重点激励项目、西部扶持项目X，每一个类别的结项编号从 001 开始。
        */
        Map<String, Integer> typeIndex = new HashMap(7);
        typeIndex.put("A", 1);
        typeIndex.put("B", 1);
        typeIndex.put("C", 1);
        typeIndex.put("Y", 1);
        typeIndex.put("D", 1);
        typeIndex.put("J", 1);
        typeIndex.put("X", 1);


        declareTopicList.forEach(item -> {
            String dictVal = item.getFinalLevelTypeVal();
            Integer integer = typeIndex.get(dictVal);
            String itemCode = "CLS(" + year + ")" + dictVal + String.format("%03d", integer);
            typeIndex.put(dictVal, ++integer);
            //设置立项编号
            item.setItemCode(itemCode);
            //设置状态
            item.setStatusTypeCode(itemPassed);
            item.setIsFinish(true);
            this.updateById(item);
        });

        //更新整个计划的状态
        topicPlanMapper.updateStatusCodeByYear(year, DictEnum.PLAN_ITEM.getCode());
    }

    @Override
    public void exportPreItemApply(Long userId, Long declareId, HttpServletResponse response) {
        //根据userId获取申请人信息
        DeclareTopicPreItemApplyExport declareTopicPreItemApplyExport = baseMapper.selectApplicantAndDeclareByUserIdAndDeclareId(userId, declareId);
        if (declareTopicPreItemApplyExport == null) {
            throw new MyException("当前用户没有申请信息！");
        }
        Calendar instance = Calendar.getInstance();
        String year = String.valueOf(instance.get(Calendar.YEAR));
        String month = String.valueOf(instance.get(Calendar.MONTH)) + 1;
        String date = String.valueOf(instance.get(Calendar.DATE));
        declareTopicPreItemApplyExport.setMakeYear(year);
        declareTopicPreItemApplyExport.setMakeMonth(month);
        declareTopicPreItemApplyExport.setApplyName(declareTopicPreItemApplyExport.getLeaderName());
        declareTopicPreItemApplyExport.setApplyYear(year);
        declareTopicPreItemApplyExport.setApplyMonth(month);
        declareTopicPreItemApplyExport.setSendYear(year);
        declareTopicPreItemApplyExport.setSendMonth(month);
        declareTopicPreItemApplyExport.setSendDay(date);
        //设置学科
        Optional.ofNullable(sysDictService.findByCode(declareTopicPreItemApplyExport.getSubjectTypeCode())).ifPresent(subjectType -> {
            declareTopicPreItemApplyExport.setSubjectType(subjectType.getName());
        });
        //设置登记
        Optional.ofNullable(sysDictService.findByCode(declareTopicPreItemApplyExport.getLevelTypeCode())).ifPresent(level -> {
            declareTopicPreItemApplyExport.setLevel(level.getName());
        });
        //成果形式
        String achievementFormTypeCode = declareTopicPreItemApplyExport.getAchievementFormTypeCode();
        if (achievementFormTypeCode != null) {
            String[] split = achievementFormTypeCode.split(",");
            List<SysDict> dicts = sysDictService.findByCodes(CollUtil.newArrayList(split));
            StringBuffer achievementFormType = new StringBuffer();
            dicts.forEach(item -> {
                achievementFormType.append(item.getName() + " ");
            });
            declareTopicPreItemApplyExport.setAchievementFormType(achievementFormType.toString());

        }

        //成果形式
        Optional.ofNullable(sysDictService.findByCode(declareTopicPreItemApplyExport.getResearchTypeCode())).ifPresent(researchType -> {
            declareTopicPreItemApplyExport.setResearchType(researchType.getName());
        });
        Optional<ApplicantInfoVO> leaderOptional = Optional.ofNullable(declareTopicPreItemApplyExport.getLeader());

        //主持人相关数据
        leaderOptional.ifPresent(leader -> {
            if (leader.getSexTypeCode() != null) {
                //主持人性别
                Optional.ofNullable(sysDictService.findByCode(leader.getSexTypeCode())).ifPresent((sex) -> {
                    leader.setSex(sex.getName());
                });
            }

            if (leader.getPositionTypeCode() != null) {
                //主持人行政职务
                Optional.ofNullable(sysDictService.findByCode(leader.getPositionTypeCode())).ifPresent(position -> {
                    leader.setPosition(position.getName());
                });
            }

            if (leader.getTitleTypeCode() != null) {
                //主持人行政职务
                Optional.ofNullable(sysDictService.findByCode(leader.getTitleTypeCode())).ifPresent(title -> {
                    leader.setTitle(title.getName());
                });
            }
            if (leader.getNationTypeCode() != null) {
                //主持人民族
                Optional.ofNullable(sysDictService.findByCode(leader.getNationTypeCode())).ifPresent(nation -> {
                    leader.setNation(nation.getName());
                });
            }
            if (leader.getPoliticalTypeCode() != null) {
                //主持人政治面貌
                Optional.ofNullable(sysDictService.findByCode(leader.getPoliticalTypeCode())).ifPresent(political -> {
                    leader.setPolitical(political.getName());
                });
            }
            if (leader.getDegreeTypeCode() != null) {
                //主持人学位
                Optional.ofNullable(sysDictService.findByCode(leader.getDegreeTypeCode())).ifPresent(degree -> {
                    leader.setDegree(degree.getName());
                });
            }
            if (leader.getTutorTypeCode() != null) {
                //主持人担任导师
                Optional.ofNullable(sysDictService.findByCode(leader.getTutorTypeCode())).ifPresent(tutor -> {
                    leader.setTutor(tutor.getName());
                });
            }

        });
        if (!leaderOptional.isPresent()) {
            declareTopicPreItemApplyExport.setLeader(new ApplicantInfoVO());
            declareTopicPreItemApplyExport.setLeaderProjects(new ArrayList<>());
        } else {
            ApplicantInfoVO leader = leaderOptional.get();
            //进行数据解密
            leader.setMobile(DESUtil.decrypt(leader.getMobile()));
            leader.setIdentity(DESUtil.decrypt(leader.getIdentity()));
            leader.setEmail(DESUtil.decrypt(leader.getEmail()));

            //主持人项目
            List<LeaderProject> leaderProjects = leaderProjectService.findByDeclareIdAndApplicantId(declareId, leader.getApplicantId());
            declareTopicPreItemApplyExport.setLeaderProjects(leaderProjects);
        }
        //参与人员
        List<MemberInfoVO> memberInfos = memberInfoService.findByDeclareId(declareId);
        declareTopicPreItemApplyExport.setMembers(memberInfos);
        String fileName = "拟立项申请书.doc";
        // 下载
        try {
            ReportUtil.generateFileByTemplate("TopicApplyWord.ftl", fileName, declareTopicPreItemApplyExport);
            FileUtil.download(fileName, fileName, true, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void exportEntrustPreItemApply(Long declareId, HttpServletResponse response) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        //根据userId获取申请人信息
        DeclareEntrustPreItemApplyExport declareEntrustPreItemApplyExport = baseMapper.exportEntrustPreItemApply(declareId);
        Date birthdayLeader = declareEntrustPreItemApplyExport.getLeader().getBirthday();
        Date birthdayMemberInfo = declareEntrustPreItemApplyExport.getMemberInfo().getBirthday();
        DateFormat ddf = DateFormat.getDateInstance();
        if (birthdayLeader!=null) {
            //出生日期
            String birthday = ddf.format(birthdayLeader);   //extractYearMonthDayOfIdCard(identityLeader);
            declareEntrustPreItemApplyExport.getLeader().setBirthdayStr(birthday);
        }
        if (birthdayMemberInfo!=null) {
            //出生日期
            String birthday =ddf.format(birthdayMemberInfo);              // extractYearMonthDayOfIdCard(identityMemberInfo);
            declareEntrustPreItemApplyExport.getMemberInfo().setBirthdayStr(birthday);
        }
        Optional<ApplicantInfoVO> leaderOptional = Optional.ofNullable(declareEntrustPreItemApplyExport.getLeader());
        leaderOptional.ifPresent(leader -> {
            //主持人性别
            Optional.ofNullable(sysDictService.findByCode(leader.getSexTypeCode())).ifPresent((sex) -> {
                leader.setSex(sex.getName());
            });
            //主持人行政职务
            Optional.ofNullable(sysDictService.findByCode(leader.getPositionTypeCode())).ifPresent(position -> {
                leader.setPosition(position.getName());
            });
            //主持人职称
            leader.setTitle(leader.getProfessionCode());

            //主持人民族
            Optional.ofNullable(sysDictService.findByCode(leader.getNationTypeCode())).ifPresent(nation -> {
                leader.setNation(nation.getName());
            });
            //主持人政治面貌
            Optional.ofNullable(sysDictService.findByCode(leader.getPoliticalTypeCode())).ifPresent(political -> {
                leader.setPolitical(political.getName());
            });
            //语言
            Optional.ofNullable(sysDictService.findByCode(leader.getLanguage())).ifPresent(language -> {
                leader.setLanguage(language.getName());
            });
            //主持人学位
            Optional.ofNullable(sysDictService.findByCode(leader.getDegreeTypeCode())).ifPresent(degree -> {
                leader.setDegree(degree.getName());
            });
            //主持人担任导师
            Optional.ofNullable(sysDictService.findByCode(leader.getTutorTypeCode())).ifPresent(tutor -> {
                leader.setTutor(tutor.getName());
            });
        });
        Optional<MemberInfoVO> memberOptional = Optional.ofNullable(declareEntrustPreItemApplyExport.getMemberInfo());
        memberOptional.ifPresent(member -> {
            //牵头人性别
            Optional.ofNullable(sysDictService.findByCode(member.getSexTypeCode())).ifPresent((sex) -> {
                member.setSex(sex.getName());
            });
            //牵头人行政职务
            Optional.ofNullable(sysDictService.findByCode(member.getPositionTypeCode())).ifPresent(position -> {
                member.setPosition(position.getName());
            });

            //政治面貌
            Optional.ofNullable(sysDictService.findByCode(member.getPoliticalTypeCode())).ifPresent(political -> {
                member.setPolitical(political.getName());
            });
            //名族
            Optional.ofNullable(sysDictService.findByCode(member.getNationTypeCode())).ifPresent(nation -> {
                member.setNation(nation.getName());
            });

        });
        //所有成员
        MemberInfo memberInfo = new MemberInfo();
        memberInfo.setDeclareId(declareId);
        memberInfo.setMemberType(1);
        List<MemberInfo> memberInfos = memberInfoService.findMemberInfos(memberInfo);

        for (MemberInfo m : memberInfos) {
            //出生日期
            String birthday = ddf.format(m.getBirthday());     //extractYearMonthDayOfIdCard(m.getIdentity());
            m.setBirthdayNyr(birthday);

            //性别
            if (StringUtils.isNotBlank(m.getSexTypeCode())) {
                SysDict byCode = sysDictService.findByCode(m.getSexTypeCode());
                if (byCode != null) {
                    m.setSexTypeCode(byCode.getName());
                }
            }
            if (StringUtils.isNotBlank(m.getPositionTypeCode())) {
                SysDict byCode = sysDictService.findByCode(m.getPositionTypeCode());
                if (byCode != null) {
                    m.setPositionTypeCode(byCode.getName());
                }
            }
            if (StringUtils.isNotBlank(m.getProfessionCode())) {
                m.setTitleTypeCode(m.getProfessionCode());
            }
            if (StringUtils.isNotBlank(m.getDegreeTypeCode())) {
                SysDict byCode = sysDictService.findByCode(m.getDegreeTypeCode());
                if (byCode != null) {
                    m.setDegreeTypeCode(byCode.getName());
                }
            }
        }

        declareEntrustPreItemApplyExport.setMembers(memberInfos);
        //项目及完成情况
        LeaderProject leaderProject = new LeaderProject();
        leaderProject.setDeclareId(declareId);
        List<LeaderProject> leaderProjects = leaderProjectService.findLeaderProjects(leaderProject);
        for (LeaderProject le : leaderProjects) {
            Date projectTime = le.getProjectTime();
            if (projectTime != null) {
                String format = sdf.format(projectTime);
                le.setProjectTimeNyr(format);
            }
            le.setIsFinishName("未结项");
            if (le.getIsFinish()) {
                le.setIsFinishName("已结项");
            }
        }
        declareEntrustPreItemApplyExport.setLeaderProjects(leaderProjects);
        //拟完成的研究成果
        DraftAchievement draftAchievement = new DraftAchievement();
        draftAchievement.setDeclareId(declareId);
        List<DraftAchievement> draftAchievementList = draftAchievementService.findDraftAchievements(draftAchievement);
        for (DraftAchievement d : draftAchievementList) {
            Date completeTime = d.getCompleteTime();
            if (completeTime != null) {
                String format = sdf.format(completeTime);
                d.setCompleteTimeNyr(format);
            }
            if (StringUtils.isNotBlank(d.getPerformance())) {
                String codes = d.getPerformance();
                String[] codeArry = codes.split(",");
                StringBuffer codeNames = new StringBuffer();
                for (String item : codeArry) {
                    //查字典
                    String name = sysDictService.findByCode(item).getName();
                    codeNames.append(" " + name);
                }
                d.setPerformance(codeNames.toString());
            }
        }
        declareEntrustPreItemApplyExport.setDraftAchievements(draftAchievementList);
        //当前时间年月
        Calendar cal = Calendar.getInstance();
        //当前年
        int yearNow = cal.get(Calendar.YEAR);
        //当前月
        int monthNow = cal.get(Calendar.MONTH) + 1;
        declareEntrustPreItemApplyExport.setYearNow(yearNow + "");
        declareEntrustPreItemApplyExport.setMonthNow(monthNow + "");

        String fileName = "委托课题申请书文件.doc";
        // 下载
        try {
            ReportUtil.generateFileByTemplate("EntrustApplyWord.ftl", fileName, declareEntrustPreItemApplyExport);
            FileUtil.download(fileName, fileName, true, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void ConclusionEntrustApply(Long declareId, HttpServletResponse response) {

        DeclareEntrustPreItemConclusionExport declareEntrustPreItemConclusionExport = new DeclareEntrustPreItemConclusionExport();
        declareEntrustPreItemConclusionExport.setDeclareId(declareId);
        DeclareTopic declareTopic = baseMapper.selectById(declareId);
        ApplicantInfo leader = applicantInfoService.getById(declareTopic.getApplicantId());
        //课题组织单位
        DeclareEntrust declareEntrust = declareEntrustMapper.findByDeclareId(declareId);
        declareEntrustPreItemConclusionExport.setTopicUnitName(declareEntrust.getTopicUnitName());
        //课题类别
        if (StringUtils.isNotBlank(declareTopic.getLevelTypeCode())) {
            String name = sysDictService.findByCode(declareTopic.getLevelTypeCode()).getName();
            declareEntrustPreItemConclusionExport.setLev(name);
        }
        //立项编号
        declareEntrustPreItemConclusionExport.setCode(declareTopic.getItemCode());
        //课题立项名称
        declareEntrustPreItemConclusionExport.setName(declareTopic.getName());
        //年度
        Topic topic = topicMapper.selectById(declareTopic.getTopicId());
        if (topic != null) {
            declareEntrustPreItemConclusionExport.setYear(topic.getYear());
        }
        //课题主持人
        declareEntrustPreItemConclusionExport.setLeaderName(declareTopic.getLeaderName());
        //主持人所在单位
        declareEntrustPreItemConclusionExport.setLeaderCompany(leader.getCompany());
        //资助经费总额
        AllotmentCapital allotmentCapitalNew = allotmentCapitalService.findNewsLog(declareId);
        if (allotmentCapitalNew != null) {
            declareEntrustPreItemConclusionExport.setTotalMoney(allotmentCapitalNew.getTotalMoney());
        }
        //已拨经费数额
        AllotmentCapital allotmentCapital = new AllotmentCapital();
        allotmentCapital.setDeclareId(declareId);
        List<AllotmentCapital> allotmentCapitalList = allotmentCapitalService.findAllotmentCapitals(allotmentCapital);
        Double money = 0.0;
        if (allotmentCapitalList != null && allotmentCapitalList.size() > 0) {
            for (AllotmentCapital a : allotmentCapitalList) {
                money += a.getAllotmentMoney();
            }
        }
        declareEntrustPreItemConclusionExport.setAllotmentMoney(money);
        //是否按期结项
        //是否提出延期申请
        DelayApply delayApply = new DelayApply();
        delayApply.setDeclareId(declareId);
        List<DelayApply> delayApplys = delayApplyService.findDelayApplys(delayApply);

        if (delayApplys != null && delayApplys.size() > 0) {
            declareEntrustPreItemConclusionExport.setIsFinsh("否");
            declareEntrustPreItemConclusionExport.setIsCommit("是");
        } else {
            declareEntrustPreItemConclusionExport.setIsFinsh("是");
        }
        //课题组成员有无变化及原因
        List<MemberInfoRecord> memberInfoRecordList = memberInfoRecordService.findLogByDeclareId(declareId);
        if (memberInfoRecordList != null && memberInfoRecordList.size() > 0) {
            StringBuffer changeName = new StringBuffer();
            for (MemberInfoRecord list : memberInfoRecordList) {
                if (DictEnum.MEMBER_ADD.getCode().equals(list.getOperationCode())) {
                    //新增
                    changeName.append("成员 " + list.getName() + "新增变化；");

                } else if (DictEnum.MEMBER_DEL.getCode().equals(list.getOperationCode())) {
                    //删除
                    changeName.append("成员 " + list.getName() + "删除变化；");

                } else if (DictEnum.MEMBER_UPDATE.getCode().equals(list.getOperationCode())) {
                    //修改
                    changeName.append("成员 " + list.getName() + "修改信息变化；");
                }
            }
            declareEntrustPreItemConclusionExport.setMemberReason(changeName.toString());
        }
        ApplicantInfoVO applicantInfoVO = new ApplicantInfoVO();
        applicantInfoVO.setApplicantId(declareTopic.getApplicantId());
        applicantInfoVO.setName(leader.getName());
        applicantInfoVO.setIdentity(leader.getIdentity());
        applicantInfoVO.setCompany(leader.getCompany());
        applicantInfoVO.setEmail(leader.getEmail());
        applicantInfoVO.setTelephone(leader.getTelephone());
        applicantInfoVO.setMobile(leader.getMobile());
        applicantInfoVO.setPostCode(leader.getPostCode());
        applicantInfoVO.setAddress(leader.getAddress());
        if (StringUtils.isNotBlank(leader.getSexTypeCode())) {
            String name = sysDictService.findByCode(leader.getSexTypeCode()).getName();
            applicantInfoVO.setSex(name);
        }
        //行政职务
        if (StringUtils.isNotBlank(leader.getPositionTypeCode())) {
            String name = sysDictService.findByCode(leader.getPositionTypeCode()).getName();
            applicantInfoVO.setPosition(name);
        }
        //主持人职称
        applicantInfoVO.setTitle(leader.getProfessionCode());

        declareEntrustPreItemConclusionExport.setLear(applicantInfoVO);

        Calendar cal = Calendar.getInstance();
        //当前年
        int yearNow = cal.get(Calendar.YEAR);
        //当前月
        int monthNow = cal.get(Calendar.MONTH) + 1;
        declareEntrustPreItemConclusionExport.setYearNow(yearNow + "");
        declareEntrustPreItemConclusionExport.setMonthNow(monthNow + "");
        //所有成员
        MemberInfo memberInfo = new MemberInfo();
        memberInfo.setDeclareId(declareId);
        memberInfo.setMemberType(1);
        List<MemberInfo> memberInfos = memberInfoService.findMemberInfos(memberInfo);
        if (memberInfos != null && memberInfos.size() > 0) {
            for (MemberInfo m : memberInfos) {
                //计算年龄
                String identity = m.getIdentity();
                if (StringUtils.isNotBlank(identity)) {
                    int dayNow = cal.get(Calendar.DATE);
                    int year = Integer.valueOf(identity.substring(6, 10));
                    int month = Integer.valueOf(identity.substring(10, 12));
                    int day = Integer.valueOf(identity.substring(12, 14));
                    if ((month < monthNow) || (month == monthNow && day <= dayNow)) {
                        m.setAge(String.valueOf(yearNow - year));
                    } else {
                        m.setAge(String.valueOf(yearNow - year - 1));
                    }
                }
                //职称
                m.setTitleTypeCode(m.getProfessionCode());
            }
        }

        declareEntrustPreItemConclusionExport.setMembers(memberInfos);

        String fileName = "结项申请书.doc";
        // 下载
        try {
            ReportUtil.generateFileByTemplate("ConclusionEntrustApply.ftl", fileName, declareEntrustPreItemConclusionExport);
            FileUtil.download(fileName, fileName, true, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    public void exportDelayApply(Long declareId, HttpServletResponse response) {

        DelayApplyExport delayApplyExport = new DelayApplyExport();

        DeclareTopic declareTopic = baseMapper.selectById(declareId);
        delayApplyExport.setDeclareId(declareTopic.getDeclareId());
        delayApplyExport.setName(declareTopic.getName());
        delayApplyExport.setCode(declareTopic.getItemCode());
        ApplicantInfo leader = applicantInfoService.getById(declareTopic.getApplicantId());
        delayApplyExport.setLeaderName(leader.getName());
        delayApplyExport.setLeaderCompany(leader.getCompany());
        delayApplyExport.setIdentity(leader.getIdentity());
        //职务
        if (StringUtils.isNotBlank(leader.getPositionTypeCode())) {
            delayApplyExport.setPosition(sysDictService.findByCode(leader.getPositionTypeCode()).getName());
        }
        //职称
        delayApplyExport.setTitle(leader.getProfessionCode());

        String fileName = "延期申请书.doc";
        // 下载
        try {
            ReportUtil.generateFileByTemplate("DelayApplyExport.ftl", fileName, delayApplyExport);
            FileUtil.download(fileName, fileName, true, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    public void exportCertificate(Long declareId, HttpServletResponse response) {
        DeclareTopic declareTopic = baseMapper.selectById(declareId);

        CertificateExport certificateExport = new CertificateExport();


        certificateExport.setCode(declareTopic.getItemCode());
        Topic topic = topicMapper.selectById(declareTopic.getTopicId());
        if (topic != null) {
            certificateExport.setYear(topic.getYear());
        }
        if (StringUtils.isNotBlank(declareTopic.getLevelTypeCode())) {
            String name = sysDictService.findByCode(declareTopic.getLevelTypeCode()).getName();
            certificateExport.setLev(name);
        }
        certificateExport.setName(declareTopic.getName());
        ApplicantInfo leader = applicantInfoService.getById(declareTopic.getApplicantId());
        if (leader != null) {
            certificateExport.setLeaderName(leader.getName());
            certificateExport.setLeaderCompany(leader.getCompany());
        }
        MemberInfo memberInfo = new MemberInfo();
        memberInfo.setDeclareId(declareId);
        memberInfo.setMemberType(1);
        List<MemberInfo> memberInfos = memberInfoService.findMemberInfos(memberInfo);
        if (memberInfos != null && memberInfos.size() > 0) {
            StringBuffer names = new StringBuffer();
            for (MemberInfo m : memberInfos) {
                names.append(m.getName() + " ");
            }
            certificateExport.setMembers(names.toString());
        }
        Calendar cal = Calendar.getInstance();
        //当前年
        int yearNow = cal.get(Calendar.YEAR);
        //当前月
        int monthNow = cal.get(Calendar.MONTH) + 1;
        int dayNow = cal.get(Calendar.DATE);
        certificateExport.setYearNow(yearNow + "");
        certificateExport.setMonthNow(monthNow + "");
        certificateExport.setDayNow(dayNow + "");
        if (StringUtils.isNotBlank(declareTopic.getFinalLevelTypeCode())) {
            String name = sysDictService.findByCode(declareTopic.getFinalLevelTypeCode()).getName();
            certificateExport.setAppraisalLev(name);
        }
        String fileName = "结项证书.doc";
        // 下载
        try {
            ReportUtil.generateFileByTemplate("ConclusionCertificate.ftl", fileName, certificateExport);
            FileUtil.download(fileName, fileName, true, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void exportNotice(Long declareId, HttpServletResponse response) {
        DeclareTopic declareTopic = baseMapper.selectById(declareId);

        ConclusionNoticeExport conclusionNoticeExport = new ConclusionNoticeExport();
        conclusionNoticeExport.setCode(declareTopic.getItemCode());
        Topic topic = topicMapper.selectById(declareTopic.getTopicId());
        if (topic != null) {
            conclusionNoticeExport.setYear(topic.getYear());
        }
        if (StringUtils.isNotBlank(declareTopic.getLevelTypeCode())) {
            String name = sysDictService.findByCode(declareTopic.getLevelTypeCode()).getName();
            conclusionNoticeExport.setLev(name);
        }
        conclusionNoticeExport.setName(declareTopic.getName());
        ApplicantInfo leader = applicantInfoService.getById(declareTopic.getApplicantId());
        if (leader != null) {
            conclusionNoticeExport.setLeaderName(leader.getName());
            conclusionNoticeExport.setLeaderCompany(leader.getCompany());
        }
        Calendar cal = Calendar.getInstance();
        //当前年
        int yearNow = cal.get(Calendar.YEAR);
        //当前月
        int monthNow = cal.get(Calendar.MONTH) + 1;
        //日
        int dayNow = cal.get(Calendar.DATE);
        conclusionNoticeExport.setYearNow(yearNow + "");
        conclusionNoticeExport.setMonthNow(monthNow + "");
        conclusionNoticeExport.setDayNow(dayNow + "");

        String fileName = "立结项通知书.doc";
        // 下载
        try {
            ReportUtil.generateFileByTemplate("ConclusionNotice.ftl", fileName, conclusionNoticeExport);
            FileUtil.download(fileName, fileName, true, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private void checkPreItemApply(Long topicId) {
        TopicPlan topicPlan = topicMapper.selectPlanByTopicId(topicId);
        Date preItemBeginTime = topicPlan.getPreItemBeginTime();
        Date date = new Date();
        int compareNoBegin = DateUtil.compare(preItemBeginTime, date);
        int compareOver = DateUtil.compare(topicPlan.getPreItemEndTime(), date);
        if (compareNoBegin > 0) {
            throw new MyException("对不起，当前课题拟立项还未开始！");
        }

        if (compareOver < 0) {
            throw new MyException("对不起，当前课题拟立项已过期！");
        }
    }

    @Override
    public void preItemApply(DeclareTopic declareTopic, Long userId) {

        checkPreItemApply(declareTopic.getTopicId());
        ApplicantInfo applicantInfo = applicantInfoService.findByUserId(userId);
        DeclareTopic declareTopicOld = this.getById(declareTopic.getDeclareId());
        if (declareTopicOld == null) {
            throw new MyException("对不起，当前申请信息不存在！");
        }
        //判断是否是本人的申请信息
        if (!applicantInfo.getApplicantId().equals(declareTopicOld.getApplicantId())) {
            throw new MyException("对不起，您提交的申请有误，不是您本人信息！");
        }
        sysFileService.updateIsFinish(declareTopic.getPreItemFileId(), declareTopicOld.getPreItemFileId());
        sysFileService.updateIsFinish(declareTopic.getApplyFileId(), declareTopicOld.getApplyFileId());
        declareTopicOld.setPreItemFileId(declareTopic.getPreItemFileId());
        declareTopicOld.setApplyFileId(declareTopic.getApplyFileId());
        //状态修改为拟立项未审查
        declareTopicOld.setStatusTypeCode(DictEnum.ITEM_NO_CHECK.getCode());
        this.updateById(declareTopicOld);
    }

    private synchronized String getMaxIndex(MaxIndex maxIndex) {
        //查看有没有这中类型的
        List<MaxIndex> maxIndexs = maxIndexService.findMaxIndex(maxIndex);
        if (maxIndexs == null || maxIndexs.size() < 1) {
            maxIndex.setMaxNum(1);
            maxIndexService.createMaxIndex(maxIndex);
        } else if (maxIndexs.size() == 1) {
            maxIndex = maxIndexs.get(0);
        } else {
            throw new IllegalArgumentException("获取序列号失败！");
        }
        int maxNum = maxIndex.getMaxNum();
        maxIndex.setMaxNum(maxNum + 1);
        maxIndexService.updateMaxIndex(maxIndex);
        return String.format("-%d", maxNum);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createOrUpdateEntrustAdd(DeclareTopicVO declareTopicVO) {
        //新增申请课题表
        DeclareTopic declareTopic = declareTopicVO.convertToDeclareTopic();
        declareTopic.setApplicantId(declareTopicVO.getLeader().getApplicantId());
        declareTopic.setLeaderName(declareTopicVO.getLeader().getName());
        declareTopic.setTopicClassifyCode(DictEnum.ENTRUST.getCode());
        //主表未申报
        declareTopic.setStatusTypeCode(DictEnum.NO_APPLY.getCode());
        this.saveOrUpdate(declareTopic);
        //修改主持人信息
        ApplicantInfo leader = declareTopicVO.getLeader();
        applicantInfoService.saveOrUpdate(leader);
        //牵头人插入
        MemberInfo memberInfo = declareTopicVO.getInitiator();
        memberInfo.setMemberType(3);
        memberInfoService.saveOrUpdate(memberInfo);
        //新增委托其他信息附表
        DeclareEntrust declareEntrust = declareTopicVO.getDeclareEntrust();
        declareEntrust.setDeclareId(declareTopic.getDeclareId());
        //初始化申请状态
        declareEntrust.setExamine(DictEnum.INFO_NO.getCode());
        declareEntrust.setInitiatorId(memberInfo.getMemberId());
        declareEntrust.setChangeCompany(leader.getCompany());
        declareEntrustService.saveOrUpdate(declareEntrust);
        //成员信息成员信息列表
        List<MemberInfo> memberInfos = declareTopicVO.getMemberInfos();
        if (memberInfos != null) {
            for (MemberInfo member : memberInfos) {
                member.setMemberType(1);
                member.setDeclareId(declareTopic.getDeclareId());
            }
            memberInfos.forEach(item->{
                memberInfoService.saveOrUpdate(item);
            });
        }
        // 获取成员研究成果信息保存与更新
        List<LeaderProject> projects = declareTopicVO.getLeaderProjects();
        if (projects != null) {
            for (LeaderProject project : projects) {
                project.setApplicantId(leader.getApplicantId());
                project.setDeclareId(declareTopic.getDeclareId());
                leaderProjectService.saveOrUpdate(project);
            }
        }
        //拟定的研究成果保存与更新
        List<DraftAchievement> draftAchievements = declareTopicVO.getDraftAchievements();
        if (draftAchievements != null) {
            for (DraftAchievement draftAchievement : draftAchievements) {
                draftAchievement.setDeclareId(declareTopic.getDeclareId());
            }
            draftAchievements.forEach(item->{
                draftAchievementService.saveOrUpdate(item);
            });
        }
        //删除成员
        List<Long> deleteMemberIds = declareTopicVO.getDeleteMemberIds();
        if (deleteMemberIds != null && deleteMemberIds.size() > 0) {
            deleteMemberIds.forEach(id ->
                    memberInfoService.removeById(id)
            );
        }
        //删除项目
        List<Long> deleteProjectIds = declareTopicVO.getDeleteProjectIds();
        if (deleteProjectIds != null && deleteProjectIds.size() > 0) {
            deleteProjectIds.forEach(id ->
                    leaderProjectService.removeById(id)
            );
        }
        //删除成果
        List<Long> deleteAchievementIds = declareTopicVO.getDeleteAchievementIds();
        if (deleteAchievementIds != null && deleteAchievementIds.size() > 0) {
            deleteAchievementIds.forEach(id ->
                    draftAchievementService.removeById(id)
            );
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeApplyDeclareTopicVO(DeclareTopicVO declareTopicVO) {
        //先变成待审核状态
        DeclareEntrust declareEntrustUp = new DeclareEntrust();
        //主持人id
        Long applicantId = declareTopicVO.getLeader().getApplicantId();
        //查询主持人单位
        ApplicantInfo applicantInfo = applicantInfoService.getById(applicantId);
        //附表信息id
        Long entrustId = declareTopicVO.getDeclareEntrust().getEntrustId();
        //毕竟是否相同
        String changeCompany = declareTopicVO.getLeader().getCompany();
        if (changeCompany == null) {
            declareEntrustUp.setChangeCompany(changeCompany);
        } else {
            if (!changeCompany.equals(applicantInfo.getCompany())) {
                //不相同
                declareEntrustUp.setChangeCompany(changeCompany);
            } else {
                //相同没有修改为原来名称
                declareEntrustUp.setChangeCompany(applicantInfo.getCompany());
            }
        }
        declareEntrustUp.setEntrustId(entrustId);
        declareEntrustUp.setExamineChange(DictEnum.CHANGE_WAIT.getCode());
        //更新信息
        declareEntrustService.saveOrUpdate(declareEntrustUp);
        //人员变动
        List<MemberInfo> memberInfos = declareTopicVO.getMemberInfos();
        List<MemberInfoRecord> memberInfoRecordList = new ArrayList<>();
        memberInfos.forEach(item -> {
            if (item.getMemberId() == null) {
                //新增
                MemberInfoRecord memberInfoRecord = item.convertToMemberInfoRecord();
                memberInfoRecord.setOperationCode(DictEnum.MEMBER_ADD.getCode());
                memberInfoRecord.setDeclareId(declareTopicVO.getDeclareId());
                memberInfoRecordList.add(memberInfoRecord);
            }
        });
        //修改对象
        Set<Long> updateMemberIds = declareTopicVO.getUpdateMemberIds();
        if (updateMemberIds != null && updateMemberIds.size() > 0) {
            for (Long id : updateMemberIds) {
                for (MemberInfo member : memberInfos) {
                    if (id.equals(member.getMemberId())) {
                        //所有修改的人员
                        MemberInfoRecord memberInfoRecordUp = member.convertToMemberInfoRecord();
                        memberInfoRecordUp.setOperationCode(DictEnum.MEMBER_UPDATE.getCode());
                        memberInfoRecordList.add(memberInfoRecordUp);
                    }
                }
            }
        }
        //删除对象
        List<Long> deleteMemberIds = declareTopicVO.getDeleteMemberIds();
        deleteMemberIds.forEach(del -> {
            MemberInfo delMember = memberInfoService.getById(del);
            MemberInfoRecord memberInfoRecord = delMember.convertToMemberInfoRecord();
            memberInfoRecord.setOperationCode(DictEnum.MEMBER_DEL.getCode());
            memberInfoRecordList.add(memberInfoRecord);
        });
        //新增到人员记录表中
        memberInfoRecordList.forEach(item -> {
            memberInfoRecordService.save(item);
        });

    }

    /**
     * 删除 委托
     *
     * @param declareId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeEntrustById(Long declareId) {
        DeclareEntrust declareEntrust = declareEntrustService.findByDeclareId(declareId);

        //主表信息
        this.removeById(declareId);
        //附表信息
        Map<String, Object> columnMap = new HashMap<>();
        columnMap.put("declare_id", declareId);
        declareEntrustService.removeByMap(columnMap);
        //获取成员研究成果信息删除
        leaderProjectService.removeByMap(columnMap);
        //拟定的研究成果删除
        draftAchievementService.removeByMap(columnMap);
        Map<String, Object> memberMap = new HashMap<>();
        memberMap.put("declare_id", declareId);
        memberMap.put("member_type", 1);
        //组成员删除
        memberInfoService.removeByMap(memberMap);
        //牵头人删除
        memberInfoService.removeById(declareEntrust.getInitiatorId());

    }

    @Override
    public DeclareTopicVO findByIdVo(long declareId) {

        DeclareTopic declareTopic = this.getById(declareId);
        DeclareTopicVO declareTopicVO = new DeclareTopicVO(declareTopic);
        //
        ApplicantInfo leader = applicantInfoService.getById(declareTopic.getApplicantId());
        if (leader != null) {
            declareTopicVO.setLeader(leader);
        }
        //附表信息
        DeclareEntrust declareEntrust = declareEntrustService.findByDeclareId(declareId);
        if (declareEntrust != null) {
            declareTopicVO.setDeclareEntrust(declareEntrust);
            //牵头人
            MemberInfo memberInfo = memberInfoService.getById(declareEntrust.getInitiatorId());

            if (memberInfo != null) {
                declareTopicVO.setInitiator(memberInfo);
            }else {
                declareTopicVO.setInitiator(new MemberInfo());
            }
        }
        //选题信息
        Topic topic = topicMapper.selectById(declareTopic.getTopicId());
        if (topic != null) {
            declareTopicVO.setTopic(topic);
        }
        declareTopicVO.setFinalLevelTypeCodeWbe(declareTopicVO.getFinalLevelTypeCode());
        //定评结果是否发布公告
        if (declareTopic.getApplyCount() != null) {
            DeclarePlan declarePlan = declareEntrustMapper.findPlan(declareTopic.getDeclareId(), declareTopic.getApplyCount());
            if (declarePlan != null) {
                TopicPlan topicPlan = topicPlanMapper.selectById(declarePlan.getPlanId());
                if (topicPlan != null) {
                    //结项通知公告
                    Long preItemNoticeId = topicPlan.getConcludeFinishNoticeId();
                    if (preItemNoticeId != null) {
                        Notice notice = Optional.of(noticeService.getById(preItemNoticeId)).orElseGet(() -> new Notice());
                        if (!notice.getIsPublish()) {
                            if (declareTopic.getStatusTypeCode().equals(DictEnum.CONCLUDE_PASSED.getCode()) || declareTopic.getStatusTypeCode().equals(DictEnum.CONCLUDE_FAILED.getCode())) {
                                declareTopicVO.setFinalLevelTypeCode(null);
                            }
                        }
                    } else {
                        if (declareTopic.getStatusTypeCode().equals(DictEnum.CONCLUDE_PASSED.getCode()) || declareTopic.getStatusTypeCode().equals(DictEnum.CONCLUDE_FAILED.getCode())) {
                            declareTopicVO.setFinalLevelTypeCode(null);
                        }
                    }
                }
            }
        }
        return declareTopicVO;
    }


    /**
     * 委托课题选择列表查询
     *
     * @param request QueryRequest
     * @param planId  Long
     * @return
     */
    @Override
    public PageInfo<SelectEntrustVO> chooseEntrusts(QueryRequest request, Long planId) {
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        Map<String, Object> param = new HashMap<>();
        param.put("planId", planId);
        List<SelectEntrustVO> declareTopicVOs = this.baseMapper.chooseEntrusts(param);
        PageInfo pageInfo = new PageInfo(declareTopicVOs);
        return pageInfo;
    }

    /**
     * 委托课题选择列表查询
     *
     * @param request QueryRequest
     * @param planId  Long
     * @return
     */
    @Override
    public PageInfo<SelectEntrustVO> assignEntrusts(QueryRequest request, Long planId) {
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<SelectEntrustVO> declareTopicVOs = this.baseMapper.assignEntrusts(planId);
        PageInfo pageInfo = new PageInfo(declareTopicVOs);
        return pageInfo;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateConclusion(DeclarePlan declarePlan, String userName, Long entrustId) {
        DeclareTopic declareTopic = new DeclareTopic();
        declareTopic.setDeclareId(declarePlan.getDeclareId());
        declareTopic.setStatusTypeCode(DictEnum.CONCLUDE_APPLY.getCode());
        //查询原来课题蛇申请次数
        DeclareTopic byId = this.getById(declarePlan.getDeclareId());
        Integer applyCount = byId.getApplyCount();
        if (applyCount == null) {
            applyCount = 0;
        }
        declareTopic.setApplyCount(applyCount + 1);
        declareTopic.setFinalLevelTypeCode("");
        this.saveOrUpdate(declareTopic);
        //第几次结项申请
        declarePlan.setApplyCount(declareTopic.getApplyCount());
        //结项申请时间
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String format = dateFormat.format(new Date());
        Date applyTime = null;
        try {
            applyTime = dateFormat.parse(format);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        declarePlan.setConclusionTime(applyTime);
        //结项申请时间
        DeclareEntrust declareEntrust = new DeclareEntrust();
        declareEntrust.setEntrustId(entrustId);
        declareEntrust.setActualTime(applyTime);
        declareEntrustService.updateDeclareEntrust(declareEntrust);
        ;
        declarePlanService.createDeclarePlan(declarePlan);

        //结项申请记录
        EntrustCheckLog entrustCheckLog = new EntrustCheckLog();
        entrustCheckLog.setCheckType(DictEnum.CONCLUDE_APPLY.getCode());
        entrustCheckLog.setDeclareId(declarePlan.getDeclareId());
        entrustCheckLog.setDeclarePlanId(declarePlan.getDeclarePlanId());
        entrustCheckLog.setCheckName(userName);
        entrustCheckLogService.createEntrustCheckLog(entrustCheckLog);
        //结项申请附件 fileApplyId
        sysFileService.updateIsFinish(declarePlan.getFileApplyId(), null);
        //显明附件 fileShowId
        sysFileService.updateIsFinish(declarePlan.getFileShowId(), null);
        //匿名附件 fileHideId
        sysFileService.updateIsFinish(declarePlan.getFileHideId(), null);
    }


    @Override
    public String getBlg(MaxIndex maxIndex) {

        String index = getMaxIndex(maxIndex);
        //修改附表
        return index;
    }

    @Override
    public List<DeclareTopic> applyCapitalDeclareTopics() {
        List<DeclareTopic> applyList = this.baseMapper.applyCapitalDeclareTopics();
        return applyList;
    }

    @Override
    public List<DeclareTopic> findAnnualDeclareTopicByPlanIdAndStatusTypeCode(Long planId, String statusTypeCode) {
        return this.baseMapper.findAnnualDeclareTopicByPlanIdAndStatusTypeCode(planId, statusTypeCode, DictEnum.ANNUAL.getCode());
    }

    @Override
    public ApplicantInfo findApplicantInfoById(Long declareTopicId) {

        return this.baseMapper.findApplicantInfoById(declareTopicId);

    }

    @Override
    public List<DeclareTopic> findFinalLevelTypeAndUserIdByPlanId(Long planId) {
        return this.baseMapper.findFinalLevelTypeAndUserIdByPlanId(planId);
    }

    @Override
    public List<DeclareTopic> selectByPlanId(Long planId) {
        return this.baseMapper.selectByPlanId(planId);
    }

    /**
     * 查询举报的课题列表
     *
     * @param planId
     * @return
     */
    @Override
    public List<DeclareTopic> reportListDeclareTopic(Long planId) {
        List<String> statusTypeCode = new ArrayList<>();
        statusTypeCode.add(DictEnum.PRE_ITEM.getCode());
        statusTypeCode.add(DictEnum.ITEM_NO_CHECK.getCode());
        statusTypeCode.add(DictEnum.ITEM_CHECK_PASSED.getCode());
        statusTypeCode.add(DictEnum.ITEM_CHECK_FAILED.getCode());
        statusTypeCode.add(DictEnum.ITEM_PASSED.getCode());
        statusTypeCode.add(DictEnum.ITEM_FAILED.getCode());
        return this.baseMapper.selectByPlanIdAndStatusTypeCode(planId, statusTypeCode);
    }


    @Override
    public void exportPreItem(String period, HttpServletResponse response) throws IOException {
        DeclareTopic declareTopic = new DeclareTopic();
        //必须查询拟立项后之后的的信息方可能展示
        List<String> codes = new ArrayList<>();
        codes.add(DictEnum.PRE_ITEM.getCode());
        codes.add(DictEnum.ITEM_NO_CHECK.getCode());
        codes.add(DictEnum.ITEM_CHECK_PASSED.getCode());
        codes.add(DictEnum.ITEM_CHECK_FAILED.getCode());
        codes.add(DictEnum.ITEM_PASSED.getCode());
        codes.add(DictEnum.ITEM_FAILED.getCode());
        codes.add(DictEnum.ITEM_CANCEL.getCode());
        declareTopic.setStatusTypeCodes(codes);
        TopicPlan topicPlan = topicPlanMapper.selectByPeriod(period);
        if (topicPlan == null) {
            throw new MyException("当前期次没有数据！");
        }

        declareTopic.setPlanId(topicPlan.getPlanId());
        List<PreItemExport> preItemExports = this.baseMapper.exportPreItem(declareTopic);
        ExcelWriter excelWriter = ExcelUtil.getWriter();
        //跳过当前行  主要是用于最后写入大标题使用
        excelWriter.passCurrentRow();
        CellStyle commonCellStyle = excelWriter.getCellStyle();
        Font font = excelWriter.createFont();
        font.setFontHeightInPoints((short) 11);
        commonCellStyle.setFont(font);
        //设置列宽
        excelWriter.setColumnWidth(0, 15);
        excelWriter.setColumnWidth(1, 30);
        excelWriter.setColumnWidth(2, 15);
        excelWriter.setColumnWidth(3, 30);
        excelWriter.setColumnWidth(4, 20);
        excelWriter.setColumnWidth(5, 20);


        //创建二级的样式
        CellStyle cellStyle2 = excelWriter.createCellStyle();
        cellStyle2.setVerticalAlignment(VerticalAlignment.CENTER);
        cellStyle2.setAlignment(HorizontalAlignment.CENTER);
        Font headFont16 = excelWriter.createFont();
        headFont16.setBold(true);
        headFont16.setFontName("宋体");
        //设置字体大小
        headFont16.setFontHeightInPoints((short) 16);
        cellStyle2.setFont(headFont16);

        //创建头部的样式
        Font headFont11 = excelWriter.createFont();
        headFont11.setBold(true);
        headFont11.setFontName("宋体");
        //设置字体大小
        headFont11.setFontHeightInPoints((short) 11);

        for (PreItemExport preItemExport : preItemExports) {

            int currentRow = excelWriter.getCurrentRow();
            Row orCreateRow = excelWriter.getOrCreateRow(currentRow);
            //注意单元格必须创建 否则自定义样式不生效
            Cell cell = orCreateRow.createCell(0);
            excelWriter.merge(6);
            cell.setCellStyle(cellStyle2);
            cell.setCellValue(preItemExport.getLevelTypeName());
            //指向下一行
            excelWriter.setCurrentRow(currentRow + 1);
            List<DeclareTopic4PreItemExport> declareTopics = preItemExport.getDeclareTopics();
            for (int i = 0; i < declareTopics.size(); i++) {
                //写标题
                if (i == 0) {
                    CellStyle headCellStyle = excelWriter.getHeadCellStyle();
                    headCellStyle.setFont(headFont11);
                    headCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
                    headCellStyle.setAlignment(HorizontalAlignment.CENTER);
                    headCellStyle.setFillForegroundColor(HSSFColor.HSSFColorPredefined.WHITE.getIndex());
                    excelWriter.writeHeadRow(CollUtil.newArrayList("课题编号", "课题名称", "主持人", "单位及职称", "主持人手机", "主持人邮箱", "课题组成员"));

                }
                DeclareTopic4PreItemExport topic = declareTopics.get(i);
                List<String> row = new ArrayList<>();
                row.add(topic.getCode());
                row.add(topic.getName());
                row.add(topic.getLeaderName());
                row.add(topic.getCompany() + "" + topic.getTitleTypeName());
                row.add(topic.getMobile());
                row.add(topic.getEmail());
                row.add(topic.getMemberName());
                excelWriter.writeRow(row);
            }
        }


        //创建头部
        Row orCreateRow = excelWriter.getOrCreateRow(0);
        //注意单元格必须创建 否则自定义样式不生效
        Cell cell = orCreateRow.createCell(0);
        //必须设置当前行，否则下面的merge就在最后一行啦。
        excelWriter.setCurrentRow(0);
        excelWriter.merge(6);
        //这里需要新创建样式
        CellStyle cellStyle = excelWriter.createCellStyle();
        cell.setCellValue("中国法学会" + period + "年度部级法学研究课题拟立项结果");
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        Font headFont20 = excelWriter.createFont();
        headFont20.setBold(true);
        headFont20.setFontName("宋体");
        //设置字体大小
        headFont20.setFontHeightInPoints((short) 20);
        cellStyle.setFont(headFont20);
        cell.setCellStyle(cellStyle);
        //设置行高
        excelWriter.setRowHeight(0, 50);
        String fileName = "拟立项结果统计.doc";
        FileUtil.downloadExcel(excelWriter, fileName, response);
    }

    public String extractYearMonthDayOfIdCard(String id) {
        String year = null;
        String month = null;
        String day = null;
        //正则匹配身份证号是否是正确的，15位或者17位数字+数字/x/X
        if (id.matches("^\\d{15}|\\d{17}[\\dxX]$")) {
            year = id.substring(6, 10);
            month = id.substring(10, 12);
            day = id.substring(12, 14);
        } else {
            System.out.println("身份证号码不匹配！");
            return "身份证号码不符合";
        }
        return year + "-" + month + "-" + day;
    }

}
